/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *      http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.wdullaer.datetimepickerexampleohos;

import com.wdullaer.EventHelper;
import com.wdullaer.materialdatetimepicker.time.AmPmCirclesView;
import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
import com.wdullaer.materialdatetimepicker.time.Timepoint;
import junit.framework.TestCase;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry;
import ohos.aafwk.ability.delegation.IAbilityDelegator;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.Calendar;

public class TimePickerTest extends TestCase {

    private static IAbilityDelegator sAbilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
    private Ability ability;

    private Button timeButton;
    private Checkbox showVersion2;
    private Checkbox mode24Hours;
    private Checkbox modeDarkTime;
    private Checkbox modeCustomAccentTime;
    private Checkbox vibrateTime;
    private Checkbox dismissTime;
    private Checkbox titleTime;
    private Checkbox enableSeconds;
    private Checkbox limitSelectableTimes;
    private Checkbox disableSpecificTimes;
    private TimePickerDialog tpd;

    private Text timePickerHeader;
    private Button mCancelButton;
    private Button mOkButton;
    private Text mHourView;
    private Text mHourSpaceView;
    private Text mMinuteView;
    private Text mMinuteSpaceView;
    private Text mSecondView;
    private Text mSecondSpaceView;
    private Text mAmTextView;
    private Text mPmTextView;
    private Component mAmPmLayout;
    private RadialPickerLayout mTimePicker;
    private AmPmCirclesView mAmPmCirclesView;

    @Before
    public void setUp() throws Exception {
        ability = EventHelper.startAbility(MainAbility.class);
        EventHelper.waitForActive(ability, 5);
        Thread.sleep(2000);
        TabList tabList = (TabList) ability.findComponentById(ResourceTable.Id_tab_list);
        sAbilityDelegator.runOnUIThreadSync(() -> tabList.selectTabAt(0));
        Thread.sleep(500);

        timeButton = (Button) ability.findComponentById(ResourceTable.Id_time_button);
        showVersion2 = (Checkbox) ability.findComponentById(ResourceTable.Id_show_version_2);
        mode24Hours = (Checkbox) ability.findComponentById(ResourceTable.Id_mode_24_hours);
        modeDarkTime = (Checkbox) ability.findComponentById(ResourceTable.Id_mode_dark_time);
        modeCustomAccentTime = (Checkbox) ability.findComponentById(ResourceTable.Id_mode_custom_accent_time);
        vibrateTime = (Checkbox) ability.findComponentById(ResourceTable.Id_vibrate_time);
        dismissTime = (Checkbox) ability.findComponentById(ResourceTable.Id_dismiss_time);
        titleTime = (Checkbox) ability.findComponentById(ResourceTable.Id_title_time);
        enableSeconds = (Checkbox) ability.findComponentById(ResourceTable.Id_enable_seconds);
        limitSelectableTimes = (Checkbox) ability.findComponentById(ResourceTable.Id_limit_times);
        disableSpecificTimes = (Checkbox) ability.findComponentById(ResourceTable.Id_disable_times);
    }

    @After
    public void tearDown() throws Exception {
    }

    private void showDialog() {
        Calendar now = Calendar.getInstance();
        if (tpd == null) {
            tpd = TimePickerDialog.newInstance(
                    ability,
                    null,
                    now.get(Calendar.HOUR_OF_DAY),
                    now.get(Calendar.MINUTE),
                    mode24Hours.isChecked()
            );
        } else {
            tpd.initialize(
                    null,
                    now.get(Calendar.HOUR_OF_DAY),
                    now.get(Calendar.MINUTE),
                    now.get(Calendar.SECOND),
                    mode24Hours.isChecked()
            );
        }
        tpd.setThemeDark(modeDarkTime.isChecked());
        tpd.vibrate(vibrateTime.isChecked());
        tpd.dismissOnPause(dismissTime.isChecked());
        tpd.enableSeconds(enableSeconds.isChecked());
        tpd.setVersion(showVersion2.isChecked() ? TimePickerDialog.Version.VERSION_2 : TimePickerDialog.Version.VERSION_1);
        if (modeCustomAccentTime.isChecked()) {
            tpd.setAccentColor(Color.getIntColor("#9C27B0"));
        }
        if (titleTime.isChecked()) {
            tpd.setTitle("TimePicker Title");
        }
        if (limitSelectableTimes.isChecked()) {
            if (enableSeconds.isChecked()) {
                tpd.setTimeInterval(3, 5, 10);
            } else {
                tpd.setTimeInterval(3, 5, 60);
            }
        }
        if (disableSpecificTimes.isChecked()) {
            Timepoint[] disabledTimes = {
                    new Timepoint(10),
                    new Timepoint(10, 30),
                    new Timepoint(11),
                    new Timepoint(12, 30)
            };
            tpd.setDisabledTimes(disabledTimes);
        }
        tpd.setOnCancelListener(dialogInterface -> {
            tpd = null;
        });
        tpd.show();
    }

    private Component loadDialogComponents() {
        Component root = ((ComponentContainer) tpd.getContentCustomComponent()).getComponentAt(0);
        timePickerHeader = (Text) root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_time_picker_header);
        mHourView = (Text)root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_hours);
        mHourSpaceView = (Text) root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_hour_space);
        mMinuteSpaceView = (Text) root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_minutes_space);
        mMinuteView = (Text) root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_minutes);
        mSecondSpaceView = (Text) root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_seconds_space);
        mSecondView = (Text) root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_seconds);
        mAmTextView = (Text) root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_am_label);
        mPmTextView = (Text) root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_pm_label);
        mAmPmLayout = root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_ampm_layout);
        mTimePicker = (RadialPickerLayout) root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_time_picker);
        mAmPmCirclesView = (AmPmCirclesView)mTimePicker.getComponentAt(1);
        mOkButton = (Button) root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_ok);
        mCancelButton = (Button) root.findComponentById(com.wdullaer.materialdatetimepicker.ResourceTable.Id_mdtp_cancel);
        return root;
    }

    @Test
    public void testShowVersion2() throws InterruptedException {
        assertNotNull(timeButton);
        assertNotNull(showVersion2);
        sAbilityDelegator.runOnUIThreadSync(() -> showVersion2.simulateClick());
        Thread.sleep(500);
        sAbilityDelegator.runOnUIThreadSync(() -> timeButton.simulateClick());
        Thread.sleep(500);

        sAbilityDelegator.runOnUIThreadSync(this::showDialog);
        Thread.sleep(1000);

        assertTrue(tpd.isShowing());
        assertEquals(TimePickerDialog.Version.VERSION_2, tpd.getVersion());

        loadDialogComponents();
        assertFalse(mAmPmCirclesView.isInitialized());
    }

    @Test
    public void testDarkMode() throws InterruptedException {
        assertNotNull(timeButton);
        assertNotNull(modeDarkTime);
        sAbilityDelegator.runOnUIThreadSync(() -> modeDarkTime.simulateClick());
        Thread.sleep(500);
        sAbilityDelegator.runOnUIThreadSync(() -> timeButton.simulateClick());
        Thread.sleep(500);

        sAbilityDelegator.runOnUIThreadSync(this::showDialog);
        Thread.sleep(1000);

        assertTrue(tpd.isShowing());

        int srcColor = ability.getColor(com.wdullaer.materialdatetimepicker.ResourceTable.Color_mdtp_light_gray);
        loadDialogComponents();
        ShapeElement element = (ShapeElement) mTimePicker.getBackgroundElement();
        RgbColor color = element.getRgbColors()[0];
        int dstColor = color.asArgbInt();

        assertEquals(srcColor, dstColor);
    }

    @Test
    public void testAccentColor() throws InterruptedException {
        assertNotNull(timeButton);
        assertNotNull(modeCustomAccentTime);
        sAbilityDelegator.runOnUIThreadSync(() -> modeCustomAccentTime.simulateClick());
        Thread.sleep(500);
        sAbilityDelegator.runOnUIThreadSync(() -> timeButton.simulateClick());
        Thread.sleep(500);

        sAbilityDelegator.runOnUIThreadSync(this::showDialog);
        Thread.sleep(1000);

        assertTrue(tpd.isShowing());

        int srcColor = Color.getIntColor("#9C27B0");
        loadDialogComponents();
        int dstColor = mOkButton.getTextColor().getValue();

        assertEquals(srcColor, dstColor);
    }

    @Test
    public void testTitle() throws InterruptedException {
        assertNotNull(timeButton);
        assertNotNull(titleTime);
        sAbilityDelegator.runOnUIThreadSync(() -> titleTime.simulateClick());
        Thread.sleep(500);
        sAbilityDelegator.runOnUIThreadSync(() -> timeButton.simulateClick());
        Thread.sleep(500);

        sAbilityDelegator.runOnUIThreadSync(this::showDialog);
        Thread.sleep(1000);

        assertTrue(tpd.isShowing());

        loadDialogComponents();
        assertEquals("TimePicker Title", timePickerHeader.getText());
    }

    @Test
    public void testSecondsPicker() throws InterruptedException {
        assertNotNull(timeButton);
        assertNotNull(enableSeconds);
        sAbilityDelegator.runOnUIThreadSync(() -> enableSeconds.simulateClick());
        Thread.sleep(500);
        sAbilityDelegator.runOnUIThreadSync(() -> timeButton.simulateClick());
        Thread.sleep(500);

        sAbilityDelegator.runOnUIThreadSync(this::showDialog);
        Thread.sleep(1000);

        assertTrue(tpd.isShowing());

        loadDialogComponents();
        assertEquals(Component.VISIBLE, mSecondView.getVisibility());
    }
}